package qc.module.ehs.api.controller;


import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.RowStyle;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import qc.common.core.constants.QCConstant;
import qc.common.core.exception.QCPromptException;
import qc.common.core.utils.DateUtil;
import qc.module.ehs.dto.report.EhsReportQueryConditionDto;
import qc.module.ehs.dto.taskitem.TaskItemInfoDto;
import qc.module.ehs.dto.troublecorrect.EhsTroubleCorrectInfoDto;
import qc.module.ehs.entity.EhsTaskItem;
import qc.module.ehs.service.EhsReportService;
import qc.module.ehs.service.EhsTaskItemService;
import qc.module.platform.dto.file.FileInfoDto;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * EhsReportController
 * @author QuCheng Tech
 * @since 2025/3/5
 */
@Slf4j
@RestController
@RequestMapping("/report")
public class EhsReportController {
    @Autowired
    private EhsReportService service;

    @Autowired
    private RestTemplatePlatform restTemplatePlatform;

    @Autowired
    private TaskItemController taskItemController;

    @Autowired
    private EhsTaskItemService taskItemService;

    @Autowired
    private TroubleCorrectController troubleCorrectController;

    /**
     * 自定义上传目录
     * file.update-path 自定义目录
     * 默认路径为：D://upload
     */
    @Value("${qucheng.upload.path:D://upload}")
    private String UPLOAD_PATH;

    /**
     * 自定义下载目录
     * file.update-path 自定义目录
     * 默认路径为：D://download
     */
    @Value("${qucheng.download.path:D://download}")
    private String DOWNLOAD_PATH;

    /***
     *  用于查询一段时间内的安全生产检查（包含自查、检查、设备维护保养）的任务项列表；
     *
     * @param dto 查询条件
     * @return java.util.List<qc.module.ehs.dto.taskitem.TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2025/3/5
     */
    @RequestMapping(value = "/inspectionquery", method = {RequestMethod.GET, RequestMethod.POST})
    public List<TaskItemInfoDto> queryInspection(@RequestBody EhsReportQueryConditionDto dto) throws QCPromptException {
        return service.queryInspection(dto);
    }

    /***
     * 用于查询一段时间内的安全生产检查（包含自查、检查、设备维护保养）的任务项列表；
     * 将任务执行情况生成word报告，包含汇总情况和逐个任务执行记录单；
     *
     * @param dto 查询条件
     * @return int 生成的报告文件ID
     * @author QuCheng Tech
     * @since 2025/3/5
     */
    @RequestMapping(value = "/inspectionreport", method = {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
    @ResponseBody
    public void generateInspectionReport(@RequestBody EhsReportQueryConditionDto dto, HttpServletResponse response) throws QCPromptException {
        List<TaskItemInfoDto> taskItems = service.queryInspection(dto);
        if (taskItems != null && taskItems.size() > 0x0) {
            String fileFullPath = generateInspectionReport(dto, taskItems);

            //文件头信息从文件中读取并进行设置
            String fileType = new MimetypesFileTypeMap().getContentType(fileFullPath);
            System.out.println("fileType=" + fileType);
            // 设置contenttype，即告诉客户端所发送的数据属于什么类型
            response.setHeader("Content-type", fileType);
            // 设置显示下载的文件名,设置字符集是避免文件名中有中文时出现乱码
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileFullPath.getBytes(), StandardCharsets.ISO_8859_1));
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");

            File file = new File(fileFullPath);
            long fileLength = file.length();
            response.addHeader("Content-Length", String.valueOf(fileLength));

            // 将文件写入输入流
            try (FileInputStream fileInputStream = new FileInputStream(file);
                 BufferedInputStream inputStream = new BufferedInputStream(fileInputStream)) {
                //修改为使用分块读，每块读完后写入
                try (ServletOutputStream outputStream = response.getOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, len);
                    }
                    outputStream.flush();
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //指定的查询条件中没有任务项记录，抛出异常进行提示
            throw new QCPromptException("没有满足查询条件的安全生产检查工作任务");
        }
    }

    /***
     * 用于查询一段时间内的安全生产检查（包含自查、检查、设备维护保养）的任务项列表；
     * 将任务执行情况生成word报告，包含汇总情况和逐个任务执行记录单；
     * @param condition 查询条件
     * @return int 生成的报告文件ID
     * @author QuCheng Tech
     * @since 2025/3/5
     */
    String generateInspectionReport(EhsReportQueryConditionDto condition, List<TaskItemInfoDto> taskItems) {
        //获取统计条件中的起止时间
        Date beginDate = DateUtil.parseDate(condition.getBegintm());
        Date endDate = DateUtil.parseDate(condition.getEndtm());
        //存放要填充的数据
        Map<String, Object> datas = new HashMap<String, Object>();

        String generateWordFileName = "安全生产任务工作报告";
        //输出为文件，指定输出文件名
        String fileUploadPath = UPLOAD_PATH + QCConstant.ROUTE_SPLIT;
        String templateFileName = "安全生产工作报告-模板.docx";
        String fileDownloadPath = DOWNLOAD_PATH + QCConstant.ROUTE_SPLIT;
        //统计条件中的起止日期
        String dateString = DateUtil.getDateString(beginDate) + "-" + DateUtil.getDateString(endDate);
        //文件名
        String destFileName = generateWordFileName + dateString + ".docx";

        try {
            datas.put("报告类型", Texts.of("检查").create());
            datas.put("报告统计时间", Texts.of(dateString).create());
            //判断如果有值时进行查询
            datas.put("单元名称", Texts.of("").create());
            datas.put("责任部门", Texts.of("").create());
            datas.put("负责人", Texts.of("").create());

            if (taskItems != null && taskItems.size() > 0x0) {
                //获取其中一条数据进行文字报告生成
                TaskItemInfoDto taskItem = taskItems.get(0x0);
                if (StringUtils.isNotBlank(condition.getUnitid())) {
                    if (condition.getUnitid().equals(taskItem.getUnitid())) {
                        datas.put("单元名称", Texts.of(taskItem.getUnitname()).create());
                    }
                }
                //按照优先级依次查询条件指定的报告部门
                if (condition.getDeptid() > 0x0) {
                    //更具部门id判断是责任部门还是转让部门
                    if (taskItem.getResdeptid() == condition.getDeptid()) {
                        datas.put("责任部门", Texts.of(taskItem.getResdeptname()).create());
                    } else if (taskItem.getTransdeptid() == condition.getDeptid()) {
                        datas.put("责任部门", Texts.of(taskItem.getTransdeptname()).create());
                    }
                }
                //判断负责任
                if (condition.getUserid() > 0x0) {
                    //根据id判断是那个责任人
                    if (taskItem.getResuserid1() == condition.getUserid()) {
                        datas.put("负责人", Texts.of(taskItem.getResusername1()).create());
                    }
                    if (taskItem.getResuserid2() == condition.getUserid()) {
                        datas.put("负责人", Texts.of(taskItem.getResusername2()).create());
                    }
                    if (taskItem.getTransuserid() == condition.getUserid()) {
                        datas.put("负责人", Texts.of(taskItem.getTransusername()).create());
                    }
                }
            }

            // 遍历任务项集合，生成汇总表表格
            // 1、创建表头行
            RowRenderData headerRow = Rows.of("序号", "任务项名称", "计划时间", "单元", "执行次数/计划次数", "执行状态", "完成时间", "责任部门/责任人")
                    .textColor("FFFFFF")
                    .bgColor("4472C4")
                    .center()
                    .create();

            // 2、确保任务项列表非空
            if (taskItems == null || taskItems.isEmpty()) {
                throw new QCPromptException("任务项列表为空");
            }

            // 3、创建数据行
            RowRenderData[] dataRows = new RowRenderData[taskItems.size()];
            for (int i = 0; i < taskItems.size(); i++) {
                TaskItemInfoDto item = taskItems.get(i);
                //确定执行转态显示文本
                String statusTest = "";
                if (item.isHasend()) {
                    statusTest = "已终止/取消";
                } else {
                    if (item.isHasfinish()) {
                        statusTest = "已完成";
                    } else {
                        statusTest = "执行中";
                    }
                }
                //处理显示所有的责任部门/责任人
                String responsibilityInfo;
                responsibilityInfo = getAllResponsibilityInfo(item);
                dataRows[i] = Rows.of(
                        String.valueOf(i + 1),
                        item.getItemname(),
                        item.getPlanbegintm() + "-" + item.getPlanendtm(),
                        item.getUnitname(),
                        item.getExeccount() + "次",
                        statusTest,// 状态字段
                        item.getExecendtm(), // 执行时间
                        responsibilityInfo  // 责任部门/责任人
                ).center().create();
            }

            // 4、先固定表格头部,然后遍历表格中的数据
            TableRenderData tableData = Tables.create(headerRow);
            if (dataRows.length > 0) {
                for (RowRenderData row : dataRows) {
                    tableData.addRow(row);
                }
            }

            // 5、将表格数据加入到数据模型中
            datas.put("汇总表格", tableData);

            // 先生成主报告
            XWPFTemplate mainTemplate = XWPFTemplate.compile(fileUploadPath + templateFileName).render(datas);
            mainTemplate.writeToFile(fileDownloadPath + destFileName);
            // 关闭模板，以便后续操作
            mainTemplate.close();

            //遍历任务项，对每个任务项获取报告文件ID（如果没有报告文件先生成报告），将报告加入到生成的文件中
            for (TaskItemInfoDto taskItem : taskItems) {
                String taskItemReportFileFullPath = null;
                int reportFileId = 0x0;
                //判断任务项是否已有报告文件，如果已有报告文件调用Platform接口获取文件完整路径；如果没有报告文件
                if (taskItem.getRptid() > 0x0) {
                    reportFileId = taskItem.getRptid();
                    FileInfoDto fileInfo = restTemplatePlatform.getFileById(reportFileId);
                    if (fileInfo != null) {
                        taskItemReportFileFullPath = fileInfo.getPath() + QCConstant.ROUTE_SPLIT + fileInfo.getName() + "." + fileInfo.getExtension();
                    }
                } else {
                    //先生成generateTaskItemReportWordFile方法需要的实体类，
                    EhsTaskItem en = taskItemService.getEntity(taskItem.getItemid());
                    //没有报告文件，调用TaskItemController中generateTaskItemReportWordFile得到报告文件完整路径
                    taskItemReportFileFullPath = taskItemController.generateTaskItemReportWordFile(en);
                }
                //使用完整的文件路径，将文件内容合并到生成的报告中
                // 合并文档
                if (taskItemReportFileFullPath != null) {
                    File file = new File(taskItemReportFileFullPath);
                    if (file.exists()) {
                        mergeWordDocuments(fileDownloadPath + destFileName, taskItemReportFileFullPath);
                    }
                }
            }
//            XWPFTemplate.compile(fileUploadPath + templateFileName).render(datas).writeToFile(fileDownloadPath + destFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //返回完整的文件路径；包含文件目录+文件名
        return fileDownloadPath + destFileName;
    }

    /**
     * 合并两个Word文档
     * @param mainDocPath   主文档路径
     * @param appendDocPath 需要追加的文档路径
     */
    private void mergeWordDocuments(String mainDocPath, String appendDocPath) {
        try (FileInputStream mainFis = new FileInputStream(mainDocPath);
             XWPFDocument mainDoc = new XWPFDocument(mainFis)) {

            try (FileInputStream appendFis = new FileInputStream(appendDocPath);
                 XWPFDocument appendDoc = new XWPFDocument(appendFis)) {

                // 1. 添加分页符
                XWPFParagraph pageBreak = mainDoc.createParagraph();
                pageBreak.setPageBreak(true);

                // 2. 复制标题
                copyTitleFromDocument(mainDoc, appendDoc);

                // 3. 复制表格
                copyTablesFromDocument(mainDoc, appendDoc);

                // 4. 保存修改后的文档
                try (FileOutputStream out = new FileOutputStream(mainDocPath)) {
                    mainDoc.write(out);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 从源文档复制标题到目标文档
     * @param destDoc 目标文档
     * @param srcDoc  源文档
     */
    private void copyTitleFromDocument(XWPFDocument destDoc, XWPFDocument srcDoc) {
        if (!srcDoc.getParagraphs().isEmpty()) {
            // 拿段落的首行
            XWPFParagraph titleParagraph = srcDoc.getParagraphs().get(0);
            // 在汇总文档中创建标题的新段落
            XWPFParagraph newTitleParagraph = destDoc.createParagraph();

            // 设置标题格式
            newTitleParagraph.setAlignment(titleParagraph.getAlignment());

            // 遍历首行段落，复制标题内容
            for (XWPFRun run : titleParagraph.getRuns()) {
                // 新段落创建
                XWPFRun newRun = newTitleParagraph.createRun();
                if (run.getText(0) != null) {
                    newRun.setText(run.getText(0));
                }

                // 复制格式
                newRun.setBold(run.isBold());
                if (run.getFontSize() != -1) {
                    newRun.setFontSize(run.getFontSize());
                }
                if (run.getFontFamily() != null) {
                    newRun.setFontFamily(run.getFontFamily());
                }
            }
        }
    }

    /**
     * 复制单元格中的图片
     * @param srcRun  源文本运行
     * @param destRun 目标文本运行
     */
    private void copyPicturesFromRun(XWPFRun srcRun, XWPFRun destRun) {
        for (XWPFPicture picture : srcRun.getEmbeddedPictures()) {
            try {
                byte[] pictureData = picture.getPictureData().getData();
                int pictureType = picture.getPictureData().getPictureType();
                String filename = picture.getPictureData().getFileName();

                // 获取图片尺寸
                int width = 0;
                int height = 0;
                try {
                    if (picture.getCTPicture() != null &&
                            picture.getCTPicture().getSpPr() != null &&
                            picture.getCTPicture().getSpPr().getXfrm() != null) {
                        width = (int) picture.getCTPicture().getSpPr().getXfrm().getExt().getCx();
                        height = (int) picture.getCTPicture().getSpPr().getXfrm().getExt().getCy();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    // 使用默认尺寸
                    width = Units.toEMU(200);
                    height = Units.toEMU(100);
                }

                // 添加图片到目标运行
                destRun.addPicture(
                        new ByteArrayInputStream(pictureData),
                        pictureType,
                        filename,
                        width,
                        height
                );
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 从源文档复制所有表格到目标文档
     * @param destDoc 目标文档
     * @param srcDoc  源文档
     */
    private void copyTablesFromDocument(XWPFDocument destDoc, XWPFDocument srcDoc) {
        for (XWPFTable srcTable : srcDoc.getTables()) {
            try {
                // 创建新表格
                XWPFTable destTable = destDoc.createTable();

                // 复制表格结构
                try {
                    // 删除目标表格的默认行
                    if (destTable.getNumberOfRows() > 0) {
                        destTable.removeRow(0);
                    }

                    // 复制表格属性，首先检查源表格CT(Complex Type)对象是否存在
                    if (srcTable.getCTTbl() != null) {
                        // TBLPr是表格属性
                        destTable.getCTTbl().setTblPr((CTTblPr) srcTable.getCTTbl().getTblPr().copy());
                        // 复制表格网格(列结构)
                        destTable.getCTTbl().setTblGrid((CTTblGrid) srcTable.getCTTbl().getTblGrid().copy());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                // 逐行复制表格内容
                for (int i = 0; i < srcTable.getNumberOfRows(); i++) {
                    XWPFTableRow srcRow = srcTable.getRow(i);
                    // 创建目标行
                    XWPFTableRow destRow = destTable.createRow();

                    // 获取源行和目标行的单元格数量
                    int srcCellCount = srcRow.getTableCells().size();
                    int destCellCount = destRow.getTableCells().size();
                    // 如果目标行单元格数量大于源行，删除多余的单元格
                    if (destCellCount > srcCellCount) {
                        // 直接访问底层XML结构删除多余的单元格
                        CTRow ctRow = destRow.getCtRow();

                        // 计算需要删除的单元格数量
                        int cellsToRemove = destCellCount - srcCellCount;

                        // 从后向前删除多余的单元格
                        for (int j = 0; j < cellsToRemove; j++) {
                            // 删除最后一个单元格
                            int lastIndex = ctRow.sizeOfTcArray() - 1;
                            if (lastIndex >= 0) {
                                ctRow.removeTc(lastIndex);
                            }
                        }
                    }

                    // 复制行高
                    destRow.setHeight(srcRow.getHeight());

                    // 复制每个单元格
                    for (int j = 0; j < srcRow.getTableCells().size(); j++) {
                        XWPFTableCell srcCell = srcRow.getCell(j);

                        // 确保目标行有足够的单元格
                        XWPFTableCell destCell;
                        if (j < destRow.getTableCells().size()) {
                            destCell = destRow.getCell(j);
                        } else {
                            destCell = destRow.createCell();
                        }
                        // 复制单元格属性（宽度、背景色等）
                        try {
                            //给目标单元格属性和结构赋值
                            if (srcCell.getCTTc() != null && srcCell.getCTTc().getTcPr() != null) {
                                destCell.getCTTc().setTcPr((CTTcPr) srcCell.getCTTc().getTcPr().copy());
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        // 复制单元格内容
                        // 先清除目标单元格默认内容
                        for (int k = destCell.getParagraphs().size() - 1; k >= 0; k--) {
                            destCell.removeParagraph(k);
                        }

                        // 复制源单元格的所有段落
                        for (XWPFParagraph srcPara : srcCell.getParagraphs()) {
                            XWPFParagraph destPara = destCell.addParagraph();

                            if (srcPara.getCTP() != null && srcPara.getCTP().getPPr() != null) {
                                destPara.getCTP().setPPr((CTPPr) srcPara.getCTP().getPPr().copy());
                            } else {
                                // 复制段落属性
                                destPara.setAlignment(srcPara.getAlignment());
                            }

                            // 复制段落中所有运行及其内容
                            for (XWPFRun srcRun : srcPara.getRuns()) {
                                XWPFRun destRun = destPara.createRun();

                                // 复制文本
                                if (srcRun.getText(0) != null) {
                                    destRun.setText(srcRun.getText(0));
                                }

                                // 复制运行的样式
                                destRun.setBold(srcRun.isBold());
                                destRun.setItalic(srcRun.isItalic());
                                if (srcRun.getFontSize() != -1) {
                                    destRun.setFontSize(srcRun.getFontSize());
                                }
                                if (srcRun.getColor() != null) {
                                    destRun.setColor(srcRun.getColor());
                                }
                                if (srcRun.getFontFamily() != null) {
                                    destRun.setFontFamily(srcRun.getFontFamily());
                                }

                                // 复制图片 (如果有)
                                if (!srcRun.getEmbeddedPictures().isEmpty()) {
                                    copyPicturesFromRun(srcRun, destRun);
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 合并所有责任人
     * @param item 传入一个实体对象
     * @return String  返回责任人添加到文档中
     */
    private String getAllResponsibilityInfo(TaskItemInfoDto item) {
        StringBuilder result = new StringBuilder();

        // 添加原始责任部门和人员
        if (item.getResdeptname() != null && !item.getResdeptname().isEmpty()) {
            result.append(item.getResdeptname()).append(" / ");

            if (item.getResusername1() != null && !item.getResusername1().isEmpty()) {
                result.append(item.getResusername1());
            }

            if (item.getResusername2() != null && !item.getResusername2().isEmpty()) {
                if (item.getResusername1() != null && !item.getResusername1().isEmpty()) {
                    result.append(", ");
                }
                result.append(item.getResusername2());
            }
        }

        // 如果有转交责任部门和人员，添加换行并附加
        if (item.getTransdeptname() != null && !item.getTransdeptname().isEmpty()) {
            if (result.length() > 0) {
                result.append("\n");
            }

            result.append(item.getTransdeptname());

            if (item.getTransusername() != null && !item.getTransusername().isEmpty()) {
                result.append(" / ").append(item.getTransusername());
            }
        }

        return result.toString();
    }

    /***
     * 用于查询一段时间内的隐患治理记录；
     *
     * @param dto 查询条件
     * @return java.util.List<qc.module.ehs.dto.troublecorrect.EhsTroubleCorrectInfoDto>
     * @author QuCheng Tech
     * @since 2025/3/5
     */
    @RequestMapping(value = "/troublequery", method = {RequestMethod.GET, RequestMethod.POST})
    public List<EhsTroubleCorrectInfoDto> queryTroubleCorrect(@RequestBody EhsReportQueryConditionDto dto) throws QCPromptException {
        return service.queryTroubleCorrect(dto);
    }

    /***
     * 用于查询一段时间内的隐患治理记录；
     * 将记录生成报告，包含汇总表和逐个隐患整理记录单；
     *
     * @param dto 查询条件
     * @return int 生成的报告文件ID
     * @author QuCheng Tech
     * @since 2025/3/5
     */
    @RequestMapping(value = "/troublereport", method = {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
    @ResponseBody
    public void generateTroubleCorrectReport(@RequestBody EhsReportQueryConditionDto dto, HttpServletResponse response) throws QCPromptException {
        List<EhsTroubleCorrectInfoDto> troubleCorrects = service.queryTroubleCorrect(dto);
        if (troubleCorrects != null && troubleCorrects.size() > 0x0) {
            //遍历任务项集合，生成汇总表表格
            //遍历任务项，对每个任务项获取报告文件ID（如果没有报告文件先生成报告），将报告加入到生成的文件中
            String fileFullPath = generateTroubleCorrectReport(dto, troubleCorrects);// generateInspectionReport(dto, null);

            //文件头信息从文件中读取并进行设置
            String fileType = new MimetypesFileTypeMap().getContentType(fileFullPath);
            System.out.println("fileType=" + fileType);
            // 设置contenttype，即告诉客户端所发送的数据属于什么类型
            response.setHeader("Content-type", fileType);
            // 设置显示下载的文件名,设置字符集是避免文件名中有中文时出现乱码
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileFullPath.getBytes(), StandardCharsets.ISO_8859_1));
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");

            File file = new File(fileFullPath);
            long fileLength = file.length();
            response.addHeader("Content-Length", String.valueOf(fileLength));

            // 将文件写入输入流
            try (FileInputStream fileInputStream = new FileInputStream(file);
                 BufferedInputStream inputStream = new BufferedInputStream(fileInputStream)) {
                //修改为使用分块读，每块读完后写入
                try (ServletOutputStream outputStream = response.getOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, len);
                    }
                    outputStream.flush();
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //指定的查询条件中没有任务项记录，抛出异常进行提示
            throw new QCPromptException("没有满足查询条件的隐患治理工作任务");
        }
    }


    /**
     * 用于查询一段时间内的隐患治理记录；
     * 将记录生成报告，包含汇总表和逐个隐患整理记录单；
     * 输出生成的报告文件流；
     * @param condition
     * @param troubleCorrects
     * @return String
     */
    String generateTroubleCorrectReport(EhsReportQueryConditionDto condition, List<EhsTroubleCorrectInfoDto> troubleCorrects) {
        //1、获取填充的时间
        Date beginTime = DateUtil.parseDate(condition.getBegintm());
        Date endTime = DateUtil.parseDate(condition.getEndtm());
        Map<String, Object> datas = new HashMap<String, Object>();

        //2、生成的word的名字
        String generateWordFileName = "安全生产工作报告";
        String filUploadPath = UPLOAD_PATH + QCConstant.ROUTE_SPLIT;
        String templateFileName = "安全生产工作报告-模板.docx";
        String fileDownloadPath = DOWNLOAD_PATH + QCConstant.ROUTE_SPLIT;
        //3、统计条件中的起止日期
        String dateString = DateUtil.getDateString(beginTime) + "-" + DateUtil.getDateString(endTime);

        //4、文件名
        String destFilePath = generateWordFileName + dateString + ".docx";

        try {
            //5、文档头部汇总信息
            //5.1 固定信息和默认为空的信息
            datas.put("报告类型", Texts.of("隐患").create());
            datas.put("时间统计报告", Texts.of(dateString).create());
            //判断如果有值进行查询
            datas.put("单位名称", Texts.of("").create());
            datas.put("责任部门", Texts.of("").create());
            datas.put("负责任", Texts.of("").create());

            //5.2 遍历数据进行填充
            if (troubleCorrects != null && troubleCorrects.size() > 0x0) {
                EhsTroubleCorrectInfoDto trouble = troubleCorrects.get(0);
                //单位名称
                if (StringUtils.isNotBlank(condition.getUnitid())) {
                    if (condition.getUnitid().equals(trouble.getUnitid())) {
                        datas.put("单位名称", Texts.of(trouble.getUnit()).create());
                    }
                }
                //责任部门
                if (condition.getDeptid() > 0x0) {
                    if (condition.getDeptid() == trouble.getResdeptid()) {
                        datas.put("责任部门", Texts.of(trouble.getResdeptname()).create());
                    }
                }
                //负责人
                if (condition.getUserid() > 0x0) {
                    if (condition.getUserid() == trouble.getResuserid()) {
                        datas.put("负责人", Texts.of(trouble.getResusername()).create());
                    }
                }
            }

            //生成表格
            //6、创建表格
            //6.1、创建表头行
            RowRenderData headerRow = Rows.of("序号", "上报/发现时间", "隐患名称", "单元", "一般/重大", "风险等级", "是否上报", "整改治理状态", "整改时限", "责任部门", "责任人", "手机号", "整改完成时间")
                    .textColor("FFFFF")
                    .bgColor("4472C4")
                    .center()
                    .rowStyle(new RowStyle())
                    .create();
            //6.2、确保任务项列表不为空
            if (CollectionUtils.isEmpty(troubleCorrects)) {
                throw new QCPromptException("项目列表为空");
            }
            List<RowRenderData> dataRows = new ArrayList<>();
            for (int i = 0x0; i < troubleCorrects.size(); i++) {
                EhsTroubleCorrectInfoDto troubleCorrect = troubleCorrects.get(i);

                dataRows.add(Rows.of(
                        String.valueOf(i + 0x1),
                        troubleCorrect.getTm(),
                        troubleCorrect.getTitle(),
                        troubleCorrect.getUnit(),
                        troubleCorrect.isIsmajor() ? "一般" : "重大",
                        String.valueOf(troubleCorrect.getRisklevel()),
                        troubleCorrect.isIsreport() ? "是" : "否",
                        troubleCorrect.isHascorrect() ? "完成" : "整改中",
                        troubleCorrect.getReqendtm(),
                        troubleCorrect.getResdeptname(),
                        troubleCorrect.getResusername(),
                        troubleCorrect.getResuserphone(),
                        troubleCorrect.getCorrectendtm()
                ).center().create());
            }
            //6.3、创建表格体
            TableRenderData tableData = Tables.create(headerRow);
            for (RowRenderData row : dataRows) {
                tableData.addRow(row);
            }

            //6.4、放入汇总表格
            datas.put("汇总表格", tableData);
            //7、先生成主报告
            XWPFTemplate mainTemplate = XWPFTemplate.compile(filUploadPath + templateFileName).render(datas);
            mainTemplate.writeToFile(fileDownloadPath + destFilePath);
            //关闭模板，以便后续操作
            mainTemplate.close();
            //8、合并隐患报告word
            //8、1遍历 隐患报告项,如果有路径通过PlatForm获取文件路
            for (EhsTroubleCorrectInfoDto troubleCorrect : troubleCorrects) {
                //声明变量保存报告文件路径
                String troubleCorrectReportFileFullPath = null;
                if (troubleCorrect.getRptid() > 0x0) {
                    FileInfoDto fileInfoDto = restTemplatePlatform.getFileById(troubleCorrect.getRptid());
                    if (fileInfoDto != null) {
                        troubleCorrectReportFileFullPath = fileInfoDto.getPath() + QCConstant.ROUTE_SPLIT + fileInfoDto.getName() + "." + fileInfoDto.getExtension();
                    }
                } else {
                    //使用generateTroubleCorrectWord先生成创建word后拿到rptid，再去获取文件路径
                    int reportFileId = troubleCorrectController.generateTroubleCorrectWord(troubleCorrect.getCorrectid());
                    FileInfoDto fileInfoDto = restTemplatePlatform.getFileById(reportFileId);
                    if (fileInfoDto != null) {
                        troubleCorrectReportFileFullPath = fileInfoDto.getPath() + QCConstant.ROUTE_SPLIT + fileInfoDto.getName() + "." + fileInfoDto.getExtension();
                    }
                }
                //8、2、通过路径读取文件，合并word
                if (StringUtils.isNotBlank(troubleCorrectReportFileFullPath)) {
                    //进行文件检查避免空指针异常
                    File file = new File(troubleCorrectReportFileFullPath);
                    if (file.exists()) {
                        mergeWordDocuments(fileDownloadPath + destFilePath, troubleCorrectReportFileFullPath);
                    }
                }
            }

            return fileDownloadPath + destFilePath;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
